package com.mes.common.condition;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;



/**
 * <p>
 * 暂不支持带括号的HQL条件语句，有一个Order By比较特殊，希望在此处予以考虑 也不支持between。使用之前首先要判断是否含有条件
 * </p>
 * 
 * <p>
 * 2009-07
 * </p>
 * 
 * @author lhy
 * 
 */
public class Conditions implements Serializable {
	private List<ConditionObjectLink> conditions;

	public Conditions() {
		super();
		conditions = new ArrayList<ConditionObjectLink>();
	}

	public Conditions(List<ConditionObjectLink> conditions) {
		super();
		this.conditions = new ArrayList<ConditionObjectLink>(conditions);
	}

	public List<ConditionObjectLink> getConditions() {
		return conditions;
	}

	public void setConditions(List<ConditionObjectLink> conditions) {
		this.conditions = new ArrayList<ConditionObjectLink>(conditions);
	}

	/**
	 * 添加一个条件，首先判断最后一个类型是不是end，是的话要先改变它的类型
	 * 
	 * @param conditions
	 */
	public void addCondition(ConditionObjectLink col) {
		if (this.conditions == null) {
			conditions = new ArrayList<ConditionObjectLink>();
		}
		if (this.conditions.size() == 0) {
			// col.setLinkType(ConditionObjectLink.END_TYPE);
			conditions.add(col);
			return;
		}
		if (this.conditions.get(this.size() - 1).getLinkType() == null
				|| "".equals(this.conditions.get(this.size() - 1).getLinkType()
						.trim())
				|| this.conditions.get(this.size() - 1).getLinkType().equals(
						ConditionObjectLink.END_TYPE)) {
			ConditionObjectLink temp = this.conditions.remove(this.conditions
					.size() - 1);
			temp.setLinkType(ConditionObjectLink.AND_TYPE);
			this.conditions.add(temp);
		}
		this.conditions.add(col);
	}

	/**
	 * 把给出的所有条件都添加进来
	 * 
	 * @param conditions
	 */
	public void addConditions(Conditions conditions) {
		if (this.conditions == null) {
			this.conditions = new ArrayList<ConditionObjectLink>();
		}
		if (this.conditions.size() == 0 && conditions.size() > 0) {
			conditions.getConditions().get(conditions.size() - 1).setLinkType(
					ConditionObjectLink.END_TYPE);
		} else if (this.conditions.size() > 0 && conditions.size() > 0) {
			this.conditions.get(this.conditions.size() - 1).setLinkType(
					ConditionObjectLink.AND_TYPE);
		}
		this.conditions.addAll(conditions.getConditions());
	}

	/**
	 * 添加一个条件，首先判断最后一个类型是不是end，是的话要先改变它的类型
	 * 
	 * @param conditions
	 * @param linkType
	 *            最后一个条件和新添加的条件的关系
	 */
	public void addCondition(ConditionObjectLink col, String linkType) {
		if (this.conditions == null) {
			conditions = new ArrayList<ConditionObjectLink>();
		}
		if (this.conditions.size() == 0) {
			col.setLinkType(ConditionObjectLink.END_TYPE);
			conditions.add(col);
			return;
		}
		if (this.conditions.get(this.size() - 1).getLinkType() == null
				|| "".equals(this.conditions.get(this.size() - 1).getLinkType()
						.trim())
				|| this.conditions.get(this.size() - 1).getLinkType().equals(
						ConditionObjectLink.END_TYPE)) {
			ConditionObjectLink temp = this.conditions.remove(this.conditions
					.size() - 1);
			temp.setLinkType(linkType);
			this.conditions.add(temp);
		}
		this.conditions.add(col);
	}

	/**
	 * 根据给出的key得到以该key为参数的对象的List，如果没有匹配返回的list的长度为0。
	 * 
	 * @param key
	 * @return
	 */
	public List<ConditionObjectLink> getConditions(String key) {
		if (key == null) {
			return null;
		}
		Iterator<ConditionObjectLink> iter = this.conditions.listIterator();
		List<ConditionObjectLink> cols = new ArrayList<ConditionObjectLink>();
		ConditionObjectLink col = null;
		while (iter.hasNext()) {
			col = iter.next();
			if (key.equalsIgnoreCase(col.getConditionObject().getKey())) {
				cols.add(col);
			}
		}
		return cols;
	}

	/**
	 * 在给出的conditions中找到key对应的值ֵ
	 * 
	 * @param conditions
	 * @param key
	 * @return
	 */
	public static String getValue(final Conditions conditions, String key) {
		if (conditions == null || key == null) {
			return null;
		}
		Iterator<ConditionObjectLink> iter = conditions.getConditions()
				.listIterator();
		String value = null;
		ConditionObjectLink col = null;
		while (iter.hasNext()) {
			col = iter.next();
			if (key.equalsIgnoreCase(col.getConditionObject().getKey())) {
				value = col.getConditionObject().getValue();
			}
		}
		return value;
	}

	/**
	 * 在给出的conditions中找到key对应的ConditionObjectLink对象
	 * 
	 * @param conditions
	 * @param key
	 * @return
	 */
	public static ConditionObjectLink getConditongObjectLink(
			final Conditions conditions, String key) {
		if (conditions == null || key == null) {
			return null;
		}
		Iterator<ConditionObjectLink> iter = conditions.getConditions()
				.listIterator();
		ConditionObjectLink col = null;
		ConditionObjectLink temp = null;

		while (iter.hasNext()) {
			col = iter.next();
			if (key.equalsIgnoreCase(col.getConditionObject().getKey())) {
				temp = col;
				break;
			}
		}
		return temp;
	}

	/**
	 * 删除一个已经存在的条件，不存在的话返回false
	 * 
	 * @param conditions
	 * @param key
	 * @return
	 */
	public static boolean removeCondition(Conditions conditions, String key) {
		if (conditions == null || key == null) {
			return false;
		}
		Iterator<ConditionObjectLink> iter = conditions.getConditions()
				.listIterator();
		ConditionObjectLink col;
		while (iter.hasNext()) {
			col = iter.next();
			if (key.equalsIgnoreCase(col.getConditionObject().getKey())) {
				conditions.removeCondition(col);
				return true;
			}
		}
		return false;
	}

	/**
	 * 删除一个已经存在的条件，不存在的话返回null
	 * 
	 * @param conditions
	 * @param key
	 * @return
	 */
	public ConditionObjectLink removeCondition(String key) {
		if (key == null) {
			return null;
		}
		Iterator<ConditionObjectLink> iter = this.getConditions()
				.listIterator();
		ConditionObjectLink col;
		ConditionObjectLink temp = null;
		while (iter.hasNext()) {
			col = iter.next();
			if (key.equalsIgnoreCase(col.getConditionObject().getKey())) {
				this.removeCondition(col);
				temp = col;
				break;
			}
		}
		return temp;
	}

	/**
	 * 是否包含key
	 * 
	 * @param conditions
	 * @param key
	 * @return
	 */
	public static boolean isContainKey(final Conditions conditions, String key) {
		if (conditions == null || conditions.size() == 0) {
			return false;
		}
		Iterator<ConditionObjectLink> iter = conditions.getConditions()
				.listIterator();
		ConditionObjectLink col;
		while (iter.hasNext()) {
			col = iter.next();
			if (key.trim().equalsIgnoreCase(
					col.getConditionObject().getKey().trim())) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 是否包含operator
	 * 
	 * @param conditions
	 * @param operator
	 * @return
	 */
	public static boolean isContainOperator(final Conditions conditions,
			String operator) {
		if (conditions == null || conditions.size() == 0) {
			return false;
		}
		Iterator<ConditionObjectLink> iter = conditions.getConditions()
				.listIterator();
		ConditionObjectLink col;
		while (iter.hasNext()) {
			col = iter.next();
			if (operator.trim().equalsIgnoreCase(
					col.getConditionObject().getOperator().trim())) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 是否包含keyType
	 * 
	 * @param conditions
	 * @param operator
	 * @return
	 */
	public static boolean isContainKeyType(final Conditions conditions,
			String keyType) {
		if (conditions == null || conditions.size() == 0) {
			return false;
		}
		Iterator<ConditionObjectLink> iter = conditions.getConditions()
				.listIterator();
		ConditionObjectLink col;
		while (iter.hasNext()) {
			col = iter.next();
			if (keyType.trim().equalsIgnoreCase(
					col.getConditionObject().getKeyType().trim())) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 还不知道是做什么用的
	 * 
	 * @param inList
	 * @return
	 */
	public static String parseStringList(List inList) {
		StringBuffer sb = new StringBuffer();
		String temp = null;
		Iterator iter = inList.iterator();
		while (iter.hasNext()) {
			String element = (String) iter.next();
			sb.append("'" + element + "'" + ",");
		}
		temp = sb.substring(0, sb.length() - 1);
		return temp;
	}

	/**
	 * 根据给出的index删除条件
	 * 
	 * @param index
	 * @return
	 */
	public ConditionObjectLink removeCondition(int index) {
		return this.getConditions().remove(index);
	}

	/**
	 * 删除条件
	 * 
	 * @param conditionObjectLink
	 * @return
	 */
	public boolean removeCondition(ConditionObjectLink conditionObjectLink) {
		return this.getConditions().remove(conditionObjectLink);
	}

	/**
	 * 得到由所有的value组成的一个数组，先把order by排除，该数组的每个变量都是一个复杂类型，代表了该参数的类型，如果是is null
	 * 或者is not null的也不做处理
	 * 
	 * @return
	 */
	public Object[] getValues() {
		if (this.conditions == null || this.conditions.size() == 0) {
			return null;
		}
		Object[] values = null;
		ConditionObjectLink orderBy = null;
		List<ConditionObjectLink> ises = new ArrayList<ConditionObjectLink>();
		ConditionObjectLink c = null;
		Iterator<ConditionObjectLink> iter;
		List<ConditionObjectLink> list = new ArrayList<ConditionObjectLink>();
		for (ConditionObjectLink col : this.conditions) {
			list.add(col);
		}
		while (true) {
			iter = list.listIterator();
			while (iter.hasNext()) {
				c = iter.next();
				// 假如是 order by
				if ("order".equalsIgnoreCase(c.getConditionObject().getKey()
						.trim())
						&& "by".equalsIgnoreCase(c.getConditionObject()
								.getOperator().trim())) {
					// 保存order by对应的condition
					orderBy = c;
					// 删除oder by对应的condition
					this.removeCondition(c);
					// continue;
				}
				if ((ConditionObject.IS_OPERATOR.equalsIgnoreCase(c
						.getConditionObject().getOperator().trim()) && "null"
						.equalsIgnoreCase(c.getConditionObject().getValue()
								.trim()))
						|| (ConditionObject.IS_NOT_OPERATOR.equalsIgnoreCase(c
								.getConditionObject().getOperator().trim()) && "null"
								.equalsIgnoreCase(c.getConditionObject()
										.getValue().trim()))) {
					// 假如是 is null或者is not null,将不予以解析
					// ises.set(j, c);
					ises.add(c);
					this.removeCondition(c);
					// continue;
				}
				if (ConditionObject.ATTIBUTE_TYPE.equalsIgnoreCase(c
						.getConditionObject().getKeyType().trim())) {
					ises.add(c);
					this.removeCondition(c);
				}
			}
			if (!isContainOperator(this, "is")
					&& !isContainOperator(this, "is not")
					&& !isContainKeyType(this, ConditionObject.ATTIBUTE_TYPE)) {
				break;
			}
		}
		values = this.getValuesIngnoreOrderBy();
		iter = ises.listIterator();
		// 删除的is null的条件添加上
		while (iter.hasNext()) {
			this.addCondition(iter.next());
		}
		if (orderBy != null) {
			orderBy.setLinkType(ConditionObjectLink.END_TYPE);
			this.addCondition(orderBy, ConditionObjectLink.AND_TYPE);
		}
		return values;
	}

	/**
	 * 得到由所有的value组成的一个数组，先把order by排除，该数组的每个变量都是一个复杂类型，代表了该参数的类型，如果是is的也不做处理
	 * 
	 * @return
	 */
	public Object[] getValuesBackup() {
		if (this.conditions == null || this.conditions.size() == 0) {
			return null;
		}
		Object[] values = null;
		ConditionObjectLink orderBy = null;
		List<ConditionObjectLink> ises = new ArrayList<ConditionObjectLink>();
		int j = 0;
		if (Conditions.isContainKey(this, "order")) {
			List<ConditionObjectLink> list = getConditions("order");
			ConditionObjectLink c = null;
			Iterator<ConditionObjectLink> iter = list.listIterator();
			while (iter.hasNext()) {
				c = iter.next();
				// 假如是 order by
				if ("by".equalsIgnoreCase(c.getConditionObject().getOperator()
						.trim())) {
					// 保存order by对应的condition
					orderBy = c;
					// 删除oder by对应的condition
					this.removeCondition(c);
					break;
				} else if ("is".equalsIgnoreCase(c.getConditionObject()
						.getOperator().trim())
						&& "null".equalsIgnoreCase(c.getConditionObject()
								.getValue().trim())) {// 假如是 is null,将不予以解析
					ises.set(j, c);
					this.removeCondition(c);
					j++;
				}
			}
			values = this.getValuesIngnoreOrderBy();
			iter = ises.listIterator();
			// 删除的is null的条件添加上
			while (iter.hasNext()) {
				this.addCondition(iter.next());
			}
			orderBy.setLinkType(ConditionObjectLink.END_TYPE);
			this.addCondition(orderBy, ConditionObjectLink.AND_TYPE);
		} else {
			values = getValuesIngnoreOrderBy();
		}
		return values;
	}

	/**
	 * 把所有的Value都组装成一个对象返回，而不管其中是否含有order by
	 * 
	 * @return
	 */
	public Object[] getValuesIngnoreOrderBy() {
		if (this.conditions == null || this.conditions.size() == 0) {
			return null;
		}
		Iterator<ConditionObjectLink> iter = conditions.listIterator();
		int i = 0;
		ConditionObjectLink col = null;
		Object[] values = new Object[this.size()];
		while (iter.hasNext()) {
			col = iter.next();
			values[i] = ConditionObject
					.getValueObject(col.getConditionObject());
			i++;
		}
		return values;
	}

	public int size() {
		return this.conditions == null ? 0 : this.conditions.size();
	}

	/*
	 * 把当前Conditions中的参数和值转化为where条件语句
	 */
	public String toString() {
		/*
		 * if (this.conditions == null || this.conditions.size() == 0) { return
		 * null; } StringBuffer temp = new StringBuffer(); ConditionObjectLink
		 * orderCondition = null; // 判断条件中是否含有order by，是的话先删除，再做处理 if
		 * (this.isContainKey(this, "order") &&
		 * "by".equalsIgnoreCase(getConditongObjectLink(this, "order")
		 * .getConditionObject().getOperator().trim())) { orderCondition =
		 * this.removeCondition("order"); // orderCondition =
		 * this.getConditongObjectLink(this, "order"); } Iterator<ConditionObjectLink>
		 * iter = this.getConditions() .listIterator(); ConditionObjectLink col;
		 * while (iter.hasNext()) { col = iter.next();
		 * temp.append(col.toString()); } String cos = temp.toString(); //
		 * 如果最后的字符串是end、and、or则去掉。 cos = removeLastLink(cos); // 加上order by操作 if
		 * (orderCondition != null) { cos = cos + " order by " +
		 * orderCondition.getConditionObject().getValue(); } return cos;
		 */
		if (this.conditions == null || this.conditions.size() == 0) {
			return null;
		}
		StringBuffer temp = new StringBuffer();
		ConditionObjectLink orderCondition = null;
		// 判断条件中是否含有order by，是的话先删除，再做处理
		if (this.isContainKey(this, "order")
				&& "by".equalsIgnoreCase(getConditongObjectLink(this, "order")
						.getConditionObject().getOperator().trim())) {
			orderCondition = this.getConditongObjectLink(this, "order");
			this.removeCondition(orderCondition);
		}
		Iterator<ConditionObjectLink> iter = this.getConditions()
				.listIterator();
		ConditionObjectLink col;
		while (iter.hasNext()) {
			col = iter.next();
			temp.append(col.toString());
		}
		String cos = temp.toString();
		// 如果最后的字符串是end、and、or则去掉。
		cos = removeLastLink(cos);
		// 加上order by操作
		if (orderCondition != null) {
			cos = cos + " order by "
					+ orderCondition.getConditionObject().getValue();

			orderCondition.setLinkType(ConditionObjectLink.END_TYPE);
			this.addCondition(orderCondition, ConditionObjectLink.AND_TYPE);
		}
		return cos;
	}

	/**
	 * 把当前Conditions中的参数和值转化为where条件语句，所有的Value都用问号代替，除了is null的情况
	 * 
	 * @return
	 */
	public String toStringWithoutValue() {
		/*
		 * if (this.conditions == null || this.conditions.size() == 0) { return
		 * ""; } StringBuffer temp = new StringBuffer(); ConditionObjectLink
		 * orderCondition = null; // 判断条件中是否含有order by，是的话先删除，再做处理 if
		 * (this.isContainKey(this, "order") &&
		 * "by".equalsIgnoreCase(getConditongObjectLink(this, "order")
		 * .getConditionObject().getOperator().trim())) { orderCondition =
		 * this.removeCondition("order"); } Iterator<ConditionObjectLink> iter =
		 * this.getConditions() .listIterator(); ConditionObjectLink col; while
		 * (iter.hasNext()) { col = iter.next();
		 * temp.append(col.toStringWithoutValue()); } String cos =
		 * temp.toString(); // 如果最后的字符串是end、and、or则去掉。 cos =
		 * removeLastLink(cos); // 加上order by操作 if (orderCondition != null) {
		 * cos = cos + " order by " +
		 * orderCondition.getConditionObject().getValue(); } return cos;
		 */
		if (this.conditions == null || this.conditions.size() == 0) {
			return "";
		}
		StringBuffer temp = new StringBuffer();
		ConditionObjectLink orderCondition = null;
		// 判断条件中是否含有order by，是的话先删除，再做处理
		if (this.isContainKey(this, "order")
				&& "by".equalsIgnoreCase(getConditongObjectLink(this, "order")
						.getConditionObject().getOperator().trim())) {
			orderCondition = this.getConditongObjectLink(this, "order");
			this.removeCondition(orderCondition);
		}
		Iterator<ConditionObjectLink> iter = this.getConditions()
				.listIterator();
		ConditionObjectLink col;
		while (iter.hasNext()) {
			col = iter.next();
			temp.append(col.toStringWithoutValue());
		}
		String cos = temp.toString();
		// 如果最后的字符串是end、and、or则去掉。
		cos = removeLastLink(cos);
		// 加上order by操作
		if (orderCondition != null) {
			cos = cos + " order by "
					+ orderCondition.getConditionObject().getValue();

			orderCondition.setLinkType(ConditionObjectLink.END_TYPE);
			this.addCondition(orderCondition, ConditionObjectLink.AND_TYPE);
		}
		return cos;
	}

	public String removeLastLink(String toRemove) {
		String temp = toRemove;
		if (temp.trim().lastIndexOf(" end") == temp.trim().length() - 4) {
			temp = temp.substring(0, temp.lastIndexOf(" end"));
		} else if (temp.trim().lastIndexOf(" and") == temp.trim().length() - 4) {
			temp = temp.substring(0, temp.lastIndexOf(" and"));
		} else if (temp.trim().lastIndexOf(" or") == temp.trim().length() - 3) {
			temp = temp.substring(0, temp.lastIndexOf(" or"));
		}
		return temp;
	}

	/**
	 * 把当前Conditions中的参数和值转化为where条件语句
	 * 
	 * @return
	 */
	public String toStringWithValue() {
		/*
		 * if (this.conditions == null || this.conditions.size() == 0) { return
		 * null; } StringBuffer temp = new StringBuffer(); ConditionObjectLink
		 * orderCondition = null; // 判断条件中是否含有order by，是的话先删除，再做处理 if
		 * (this.isContainKey(this, "order") &&
		 * "by".equalsIgnoreCase(getConditongObjectLink(this, "order")
		 * .getConditionObject().getOperator().trim())) { orderCondition =
		 * this.removeCondition("order"); } Iterator<ConditionObjectLink> iter =
		 * this.getConditions() .listIterator(); ConditionObjectLink col; while
		 * (iter.hasNext()) { col = iter.next();
		 * temp.append(col.toStringWithValue()); } String cos = temp.toString(); //
		 * 如果最后的字符串是end、and、or则去掉。 cos = removeLastLink(cos); // 加上order by操作 if
		 * (orderCondition != null) { cos = cos + " order by " +
		 * orderCondition.getConditionObject().getValue(); } return cos;
		 */
		if (this.conditions == null || this.conditions.size() == 0) {
			return null;
		}
		StringBuffer temp = new StringBuffer();
		ConditionObjectLink orderCondition = null;
		// 判断条件中是否含有order by，是的话先删除，再做处理
		if (this.isContainKey(this, "order")
				&& "by".equalsIgnoreCase(getConditongObjectLink(this, "order")
						.getConditionObject().getOperator().trim())) {
			orderCondition = this.getConditongObjectLink(this, "order");
			this.removeCondition(orderCondition);
		}
		Iterator<ConditionObjectLink> iter = this.getConditions()
				.listIterator();
		ConditionObjectLink col;
		while (iter.hasNext()) {
			col = iter.next();
			temp.append(col.toStringWithValue());
		}
		String cos = temp.toString();
		// 如果最后的字符串是end、and、or则去掉。
		cos = removeLastLink(cos);
		// 加上order by操作
		if (orderCondition != null) {
			cos = cos + " order by "
					+ orderCondition.getConditionObject().getValue();

			orderCondition.setLinkType(ConditionObjectLink.END_TYPE);
			this.addCondition(orderCondition, ConditionObjectLink.AND_TYPE);
		}
		return cos;
	}
}
